package com.oa.tools.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;

public class FileUtil {
	public static File newFile(String fullPath) {
		File file = new File(fullPath);
		try {
			if ((!file.exists()) && (file.isFile())) {
				file.getParentFile().mkdirs();
				file.createNewFile();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;
	}

	public static OutputStream openOutputStream(File file) throws Exception {
		FileOutputStream fos = new FileOutputStream(file);
		return fos;
	}

	public static void closeStream(OutputStream os) {
		if (os != null)
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}

	public static void closeStream(InputStream is) {
		if (is != null)
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}

	public static String readTxt(String path, String charset) throws Exception {
		StringBuffer result = new StringBuffer();

		FileInputStream fis = new FileInputStream(path);
		BufferedReader br = new BufferedReader(new InputStreamReader(fis, charset));

		String line = null;

		while ((line = br.readLine()) != null) {
			result.append(line);
		}

		br.close();

		return result.toString();
	}

	public static void readTxtAndHandle(String path, String charset, StringHandler handler) {
		FileInputStream fis = null;

		BufferedReader br = null;
		try {
			fis = new FileInputStream(path);

			br = new BufferedReader(new InputStreamReader(fis, charset));

			String line = null;

			while ((line = br.readLine()) != null) {
				handler.doHandler(line);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (fis != null) {
						fis.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void listFile(File root, List<File> allFiles) {
		if ((root.exists()) && (root.isDirectory())) {
			File[] children = root.listFiles();

			if ((children != null) && (children.length > 0)) {
				for (File child : children) {
					if (child.isFile()) {
						if (!child.isHidden())
							allFiles.add(child);
					} else
						listFile(child, allFiles);
				}
			}
		} else {
			System.err.println("文件不存在，或不是文件夹！");
		}
	}

	public static void listFile(File root, List<File> allFiles, int maxDepth) {
		maxDepth--;

		if ((root.exists()) && (root.isDirectory())) {
			File[] children = root.listFiles();
			if ((children != null) && (children.length > 0)) {
				for (File child : children) {
					if (child.isFile()) {
						if (!child.isHidden()) {
							System.out.println(child);
						}
					} else if (maxDepth > 0)
						listFile(child, allFiles, maxDepth);
					else
						allFiles.add(child);
				}
			}
		} else {
			System.err.println("文件不存在，或不是文件夹！");
		}
	}

	public static List<String> readTxt2List(String path, String charSet) {
		List<String> result = new ArrayList<String>();

		FileInputStream fis = null;

		BufferedReader br = null;
		try {
			fis = new FileInputStream(path);

			br = new BufferedReader(new InputStreamReader(fis, charSet));

			String line = null;

			while ((line = br.readLine()) != null)
				result.add(line);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (fis != null)
						fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	public static List<String> readTxt2List(InputStream fis, Charset charSet) {
		List<String> result = new ArrayList<String>();

		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(fis, charSet));

			String line = null;

			while ((line = br.readLine()) != null)
				result.add(line);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (fis != null)
						fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	public static void writeTxt2File(String content, String savePath) {
		File file = new File(savePath);

		File pfile = file.getParentFile();
		if(pfile!=null) {
			pfile.mkdirs();
		}

		FileOutputStream fos = null;

		PrintWriter pw = null;
		try {
			fos = new FileOutputStream(file, true);

			pw = new PrintWriter(fos);

			pw.println(content);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pw != null)
				pw.close();
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void writeTxt2File(String content, String savePath,Charset charset,boolean isAppend) {
		File file = new File(savePath);
		File pfile = file.getParentFile();
		if(pfile!=null) {
			pfile.mkdirs();
		}

		FileOutputStream fos = null;
		OutputStreamWriter osw = null;
		PrintWriter pw = null;
		try {
			fos = new FileOutputStream(file,isAppend);
			osw = new OutputStreamWriter(fos, charset);
			pw = new PrintWriter(fos);

			pw.println(content);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pw != null)
				pw.close();
			try {
				if (osw != null)
					osw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				try {
					if (fos != null)
						fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	public static byte[] readFileToByte(String filePath) {
		FileInputStream fis = null;

		byte buf[] = new byte[0];
		try {
			fis = new FileInputStream(filePath);
			buf = new byte[fis.available()];
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return buf;
	}
	
	public static InputStream readFile(String filePath) {
		FileInputStream fis = null;

		try {
			fis = new FileInputStream(filePath);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
//			try {
//				if (fis != null)
//					fis.close();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
		}
		
		return fis;
	}

	public static String[][] readCsv(String csvFile, String charSet) {
		String[][] result = (String[][]) null;
		try {
			List<String> data = readTxt2List(csvFile, charSet);

			int len = data.size();

			result = new String[len][];

			for (int i = 0; i < len; i++) {
				String line = (String) data.get(i);
				String[] lineData = line.split("[,，]");
				result[i] = lineData;
			}
		} catch (Throwable e) {
			System.err.println("errFile：" + csvFile);
			e.printStackTrace();
		}
		return result;
	}
	
	public static Properties loadProps(InputStream inStream){
		Properties props = new Properties();
		try {
			props.load(inStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return props;
	}

	public static abstract interface StringHandler {
		public abstract void doHandler(String paramString);
	}
	
	/*
	 *	获取ZIP文件中的文件名和目录名
	 */
    public  static List<String> getEntryNames(String zipFilePath, String password){
        List<String> entryList = new ArrayList<String>();
        ZipFile zf;
        try {
            zf = new ZipFile(zipFilePath);
            zf.setFileNameCharset("gbk");//默认UTF8，如果压缩包中的文件名是GBK会出现乱码
            if(zf.isEncrypted()){
                zf.setPassword(password);//设置压缩密码
            }
            for(Object obj : zf.getFileHeaders()){
                FileHeader fileHeader = (FileHeader)obj;
                String fileName = fileHeader.getFileName();//文件名会带上层级目录信息
                entryList.add(fileName);
            }
        } catch (ZipException e) {
            e.printStackTrace();
        }
        return entryList;
    }

    /*
    	将ZIP包中的文件解压到指定目录
    */
    public static void extract(String zipFilePath, String password, String destDir){
        InputStream is = null;
        OutputStream os = null;
        ZipFile zf;
        int BUFF_SIZE = 4096;
        
        try {
            zf = new ZipFile(zipFilePath);
            zf.setFileNameCharset("gbk");
            if(zf.isEncrypted()){
                zf.setPassword(password);
            }
            
            for(Object obj : zf.getFileHeaders()){
                FileHeader fileHeader = (FileHeader)obj;
                String destPath = destDir + "/" + fileHeader.getFileName();
                File destFile = new File(destPath);
                if(!destFile.getParentFile().exists()){
                    destFile.getParentFile().mkdirs();//创建目录
                }
                is = zf.getInputStream(fileHeader);
                os = new FileOutputStream(destFile);
                int readLen = -1;
                byte[] buff = new byte[BUFF_SIZE];
                while ((readLen = is.read(buff)) != -1) {
                    os.write(buff, 0, readLen);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //关闭资源
            try{
                if(is != null){
                    is.close();
                }
            }catch(IOException ioe){}
            
            try{
                if(os != null){
                    os.close();
                }
            }catch(IOException ioe){}
        }
    }
}